window.onload = function () {
  let flag: boolean = false; //布尔类型
  let num: number = 15; //数值尖型
  let str: string = "abc"; // 字符申类型
  let str2: string = `hello,${str}`;
  let msg: string = `hello,${str},${num} `;
  let u: undefined = undefined;
  let n: null = null;
  let a: number = 10;
  a = 3;
  //联合类型
  let x: number | string = "10";
  x = 10;
  // 任意 类型
  let y: any = true;
  y = 10;
  y = "10";
  //引用类型 数组 对象 函数
  // 数组类型+方括号
  let arr: number[] = [1, 2, 3, 4, 5];
  let arr1: string[] = ["a", "b", "c", "d", "e"];
  let arr2: (number | string)[] = [1, 2, "c", "d", "e"]; //联合类型
  let arr4: any[] = [1, 2, "a", true];
  //  泛型(Generics) 是指在定义函数、接口或类的时候，类型的一种特性 不预先指定具体的类型，而在使用的时候再指定类型的一种特性
  //
  // 泛型变量T
  // T表示任何类型

  // 数组泛型
  let arr5: Array<number> = [1, 2, 3, 4, 5];
  let arr6: Array<string> = ["a", "b", "c"];
  let arr7: Array<number | string> = [1, 2, "a", "b", 5];

  //对象object
  // 在面向对象语言中，接口（Interfaces）是一个很重要的概念，她是对行为的抽象
  interface IObj {
    id: number; // 确定属性
    name?: string; // ?可选
    [proName: string]: any; //任意属性
  }
  let o1: IObj = {
    id: 1,
    name: "inzv",
    fu: function () {},
    a: "1",
    b: 3,
  };
  //数组对象
  interface IList {
    id: number;
    text: string;
  }
  let lists: IList[] = [
    {
      id: 1,
      text: "a",
    },
    {
      id: 2,
      text: "b",
    },
    {
      id: 3,
      text: "c",
    },
  ];
  let lists2: Array<IList> = [
    {
      id: 1,
      text: "a",
    },
    {
      id: 2,
      text: "b",
    },
    {
      id: 3,
      text: "c",
    },
  ];
  //函数 输入类型 输出类型
  function sum(n1: number, n2: string): Array<number | string> {
    return [n1, n2];
  }
  sum(10, "20");
  //void 无返回值
  function fn(n1: number, n2?: number): void {
    // if(n1>n2){
    //     //...
    // }
  }
  fn(10, 5);

  //  泛型(Generics) 是指在定义函数、接口或类的时候，类型的一种特性 不预先指定具体的类型，而在使用的时候再指定类型的一种特性
  function sum2(n1: string, n2: string): Array<string> {
    return [n1, n2];
  }
  sum2("10", "20");
  function sum3(n1: number, n2: number): Array<number> {
    return [n1, n2];
  }
  sum3(10, 2);
  function sum4(n1: boolean, n2: boolean): Array<boolean> {
    return [n1, n2];
  }
  sum4(true, false);
  function sum5<T>(n1: T, n2: T): Array<T> {
    return [n1, n2];
  }
  sum5<number>(1, 2);
  // sum5('a','b'); // 类型推断
  sum5<string>("a", "b"); // 类型推断
  sum5<boolean>(true, false);
  // sum5(true,false);

  //泛型约束
  interface Ilength {
    length: number;
  }
  // <T extends Ilength> 必须要有长度属性
  function fn2<T extends Ilength>(v: T): number {
    return v.length; // v的类型是任何类型
  }
  fn2<string>("hello");
  // fn2<number>(100);
  fn2<number[]>([1, 2, 3]);

  //泛型接口
  //定义一个函数，判断形参是否一样
  let f1 = function (n1, n2) {
    return n1 === n2;
  };
  f1(10, 20);
  //添加类型约束
//   let f2 = function (n1: number, n2: number): boolean {
//     return n1 === n2;
//   };
//   f2(10, 20);
  //定义另一个函数
  let f3 = function (x, y) {
    if (x > y) {
      return true;
    } else {
      return false;
    }
  };
  f3(10, 20);
  // 添加类型约束
//   let f4 = function (x: number, y: number): boolean {
//     if (x > y) {
//       return true;
//     } else {
//       return false;
//     }
//   };

  // 接口 
  // 第二种写法  interface IinspectFn<T> {
   interface IinspectFn {
    <T>(a: T, b: T): boolean
   };
//    let f2:IinspectFn<number>  = function(n1, n2) {
   let f2:IinspectFn = function <T>(n1, n2) {
    return n1 === n2;
    };
    f2<number>(10,20)
    // f2(10,20)
    let f4:IinspectFn = function <T>(x, y) {
    // let f4:IinspectFn<string> = function (x, y) {
        if (x > y) {
          return true;
        } else {
          return false;
        }
      };
      f4<string>('10','20')
};
